//
//  APITest.swift
//  file-server-2.0
//
//  Created by wlx on 17/3/31.
//
//

import Foundation
import Kitura
import SwiftyJSON
import KituraCSRF
import KituraSession
import Darwin

import SwiftKuery
import SwiftKueryPostgreSQL

import KituraSampleRouter
import KituraSessionRedis


typealias PropValue = AnyObject

class Grades : Table {
    let tableName = "grades"
    let key = Column("key")
    let course = Column("course")
    let grade = Column("grade")
    let studentId = Column("studentId")
}

let grades = Grades()

let connection = PostgreSQLConnection(host: "localhost", port: 5432, options: [.databaseName("school")])

func grades(_ callback:@escaping (String)->Void) -> Void {
    connection.connect() { error in
        if let error = error {
            callback("Error is \(error)")
            return
        }
        else {
            // Build and execute your query here.
            
            // First build query
//            let query = Select(grades.course, grades.grade, from: grades)
            let query = Select(grades.course, grades.grade, from: grades).where(grades.grade > 80)
            
            connection.execute(query: query) { result in
                if let resultSet = result.asResultSet {
                    var retString = ""
                    
                    for title in resultSet.titles {
                        // The column names of the result.
                        retString.append("\(title.padding(toLength: 35, withPad: " ", startingAt: 0))")
                    }
                    retString.append("\n")
                    
                    for row in resultSet.rows {
                        for value in row {
                            if let value = value {
                                let valueString = String(describing: value)
                                retString.append("\(valueString.padding(toLength: 35, withPad: " ", startingAt: 0))")
                            }
                        }
                        retString.append("\n")
                    }
                    callback(retString)
                }
                else if let queryError = result.asError {
                    // Something went wrong.
                    callback("Something went wrong \(queryError)")
                    
                }
            }
        }
    }
}

func PostgreSQL() {
    router.get("/") {
        request, response, next in
        grades() {
            resp in
            response.send(resp)
            next()
        }
    }
}

func api1()
{
    router.post("/save") {request, response, next in
        response.headers["Content-Type"] = "text/plain; charset=utf-8"
        let js = JSON.parse(string: try request.readString()!)
        let image = js["image"].string ?? ""
        let na = js["name"].string ?? ""
        saveImg(name: na, str: image)
        try response.send("Got a POST request").end()
        
        let name = request.body?.asJSON?["name"].string ?? ""
        print(name)
        
    }
    
}


func api2() {
    struct UserInfo {
        var username : String
        var pwd : String
        var other : [String:[Int]]// ["str":[21,22,23], "str":[1,2,3]]
    }
        
//    router.all(middleware: Session(secret: "qwerasdf"))
    //        router.all(middleware: CSRF())
    
    let csrf1 = CSRF()
    let csrf2 = CSRF(retrieveToken: retrieveToken)
    let csrf3 = CSRF(ignoredMethods: [], retrieveToken: retrieveToken)
    
    router.all("/qwerget", middleware: csrf1)
    
    router.get("/qwerget") { request, response, next in
        let token = csrf1.createToken(request: request)
        tokens = token!
        response.headers["csrf-token"] = tokens
        request.session?[sessionTestKey] = JSON(sessionTestValue as PropValue)
        response.status(.noContent)
        let params = request.queryParameters
        print(params)
        let username = params["username"]! as String
        let pwd = params["pwd"]! as String
        //cache
        cache.removeObject(forKey: "UserInfo")
        let value1 =  UserInfo(username: username, pwd: pwd, other: ["qwer":[1,2,3], "www":[1,2,3]])
        cache.setObject(value1, forKey: "UserInfo")
        
        if params["username"]! as String == "520"
        {
            var jsonResponse = JSON([:])
            jsonResponse["token"].stringValue = token!
            response.status(.OK).send(json: jsonResponse)
        }else{
            response.status(.OK).send("Not Got The request!")
        }
        next()
    }
    
    router.post("/qwerpost") { request, response, next in
        response.status(.noContent)
        response.headers["Content-Type"] = "text/plain; charset=utf-8"
        let js = JSON.parse(string: try request.readString()!)
        print("post",js)
        //cache
        let obj2 = cache.object(forKey: "UserInfo")
        let object2 = obj2 as! UserInfo
        print(object2.username,object2.pwd)
        
        if js["token"].string == tokens {
            response.headers["Content-Type"] = "application/json; charset=utf-8"
            var jsonResponse = JSON([:])
            jsonResponse["kuoyi"].stringValue = "123we12rweq1r234"
            jsonResponse["kuwqe"].stringValue = "123we12rweq1r234"
            jsonResponse["wwww"].stringValue = "123we12rweq1r234"
            response.status(.OK).send(json: jsonResponse)
        } else {
            try response.status(.OK).send("Not Got The request!").end()
        }
        next()
    }
    
    
    router.all("/zxcv", middleware: csrf2)
    router.get("/zxcv") { request, response, next in
        let token = csrf2.createToken(request: request)
        response.headers["lalala-token"] = token
        request.session?[sessionTestKey] = JSON(sessionTestValue as PropValue)
        response.status(.noContent)
        
        next()
    }
    router.post("/zxcv") { request, response, next in
        response.status(.noContent)
        next()
    }
    
    router.all("/asdf", middleware: csrf3)
    router.get("/asdf") { request, response, next in
        let token = csrf3.createToken(request: request)
        response.headers["csrf-token"] = token
        request.session?[sessionTestKey] = JSON(sessionTestValue as PropValue)
        response.status(.noContent)
        
        response.headers["Content-Type"] = "application/json; charset=utf-8"
        var jsonResponse = JSON([:])
        jsonResponse["framework"].stringValue = "Kitura"
        jsonResponse["location"].stringValue = "Austin, Texas"
        response.status(.OK).send(json: jsonResponse)
        next()
    }
}

func retrieveToken(request: RouterRequest) -> String? {
    return request.headers["lalala-token"]
}

func read(fileName: String) -> String {
    // Read in a configuration file into an NSData
    let fileData: Data
    
    let sourceFileName = NSString(string: #file)
    let pathToTestsPrefixRange: NSRange
    let lastSlash = sourceFileName.range(of: "/", options: .backwards)
    if  lastSlash.location != NSNotFound {
        pathToTestsPrefixRange = NSMakeRange(0, lastSlash.location+1)
    } else {
        pathToTestsPrefixRange = NSMakeRange(0, sourceFileName.length)
    }
    let pathToTests = sourceFileName.substring(with: pathToTestsPrefixRange)
    
    do {
        fileData = try Data(contentsOf: URL(fileURLWithPath: "\(pathToTests)\(fileName)"))
    }
    catch {
        //            XCTFail("Failed to read in the \(fileName) file [\(pathToTests)\(fileName)]")
        exit(1)
    }
    
    let resultString = String(data: fileData, encoding: .utf8)
    
    guard
        let resultLiteral = resultString
        else {
            //                XCTFail("Error in \(fileName).")
            exit(1)
    }
    return resultLiteral.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
}

